using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using BanZuiCloudControlAgent.Core.Tasks.Base;
using BanZuiCloudControlAgent.Core.Tasks.Enums;
using BanZuiCloudControlAgent.Core.Tasks.Models;
using BanZuiCloudControlAgent.Utils.Logging;
 

namespace BanZuiCloudControlAgent.Core.Tasks.Queue
{
    /// <summary>
    /// 任务执行委托，用于自定义任务执行逻辑
    /// </summary>
    /// <param name="task">要执行的任务</param>
    /// <param name="context">任务上下文</param>
    /// <returns>任务执行结果</returns>
    public delegate Task<TaskResult> ExecuteTaskDelegate(ITask task, TaskContext context);
    
    /// <summary>
    /// 任务队列，用于管理任务的排队和执行
    /// </summary>
    public class TaskQueue
    {
        /// <summary>
        /// 日志记录器
        /// </summary>
        private readonly Logger _logger;
        
        /// <summary>
        /// 任务队列
        /// </summary>
        private readonly ConcurrentQueue<BaseTask> _taskQueue;
        
        /// <summary>
        /// 正在执行的任务
        /// </summary>
        private readonly ConcurrentDictionary<string, BaseTask> _runningTasks;
        
        /// <summary>
        /// 已完成的任务
        /// </summary>
        private readonly ConcurrentDictionary<string, BaseTask> _completedTasks;
        
        /// <summary>
        /// 任务执行线程是否正在运行
        /// </summary>
        private bool _isRunning;
        
        /// <summary>
        /// 取消令牌源
        /// </summary>
        private CancellationTokenSource _cancellationTokenSource;
        
        /// <summary>
        /// 最大并行任务数
        /// </summary>
        private int _maxParallelTasks;
        
        /// <summary>
        /// 自定义任务执行委托
        /// </summary>
        private ExecuteTaskDelegate _executeTaskDelegate;
        
        /// <summary>
        /// 任务状态变更事件
        /// </summary>
        public event EventHandler<TaskStatusChangedEventArgs> TaskStatusChanged;
        
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="maxParallelTasks">最大并行任务数</param>
        public TaskQueue(int maxParallelTasks = 3)
        {
            _logger = LogManager.GetLogger(nameof(TaskQueue));
            _taskQueue = new ConcurrentQueue<BaseTask>();
            _runningTasks = new ConcurrentDictionary<string, BaseTask>();
            _completedTasks = new ConcurrentDictionary<string, BaseTask>();
            _maxParallelTasks = maxParallelTasks;
            _isRunning = false;
            
            // 默认使用直接执行任务的委托
            _executeTaskDelegate = DefaultExecuteTaskAsync;
        }
        
        /// <summary>
        /// 设置任务执行委托
        /// </summary>
        /// <param name="executeTaskDelegate">任务执行委托</param>
        public void SetExecuteTaskDelegate(ExecuteTaskDelegate executeTaskDelegate)
        {
            _executeTaskDelegate = executeTaskDelegate ?? DefaultExecuteTaskAsync;
            _logger.Info("已设置自定义任务执行委托");
        }
        
        /// <summary>
        /// 默认的任务执行方法
        /// </summary>
        /// <param name="task">要执行的任务</param>
        /// <param name="context">任务上下文</param>
        /// <returns>任务执行结果</returns>
        private async Task<TaskResult> DefaultExecuteTaskAsync(ITask task, TaskContext context)
        {
            return await task.ExecuteAsync(context);
        }
        
        /// <summary>
        /// 启动任务队列
        /// </summary>
        public void Start()
        {
            if (_isRunning)
            {
                _logger.Warn("任务队列已经在运行中");
                return;
            }
            
            _isRunning = true;
            _cancellationTokenSource = new CancellationTokenSource();
            
            _logger.Info("任务队列已启动");
            
            // 启动任务处理线程
            Task.Run(() => ProcessTasksAsync(_cancellationTokenSource.Token));
        }
        
        /// <summary>
        /// 停止任务队列
        /// </summary>
        public void Stop()
        {
            if (!_isRunning)
            {
                _logger.Warn("任务队列已经停止");
                return;
            }
            
            _isRunning = false;
            _cancellationTokenSource?.Cancel();
            
            _logger.Info("任务队列已停止");
        }
        
        /// <summary>
        /// 添加任务到队列
        /// </summary>
        /// <param name="task">任务</param>
        /// <returns>任务ID</returns>
        public async Task<string> EnqueueAsync(BaseTask task)
        {
            // 订阅任务的进度变化事件
            task.ProgressChanged += Task_ProgressChanged;
            
            _taskQueue.Enqueue(task);
            _logger.Info($"任务已加入队列: {task.TaskId}, 类型: {task.TaskType}");
            
            OnTaskStatusChanged(new TaskStatusChangedEventArgs(task, TaskState.Pending));
            
            return task.TaskId;
        }
        
        /// <summary>
        /// 暂停任务
        /// </summary>
        /// <param name="taskId">任务ID</param>
        /// <returns>是否成功</returns>
        public async Task<bool> PauseTaskAsync(string taskId)
        {
            // 检查正在运行的任务
            if (_runningTasks.TryGetValue(taskId, out BaseTask runningTask))
            {
                await runningTask.PauseAsync();
                _logger.Info($"任务已暂停: {taskId}");
                OnTaskStatusChanged(new TaskStatusChangedEventArgs(runningTask, TaskState.Paused));
                return true;
            }
            
            // 检查队列中的任务
            var queuedTask = _taskQueue.FirstOrDefault(t => t.TaskId == taskId);
            if (queuedTask != null)
            {
                await queuedTask.PauseAsync();
                _logger.Info($"队列中的任务已暂停: {taskId}");
                OnTaskStatusChanged(new TaskStatusChangedEventArgs(queuedTask, TaskState.Paused));
                return true;
            }
            
            _logger.Warn($"找不到要暂停的任务: {taskId}");
            return false;
        }
        
        /// <summary>
        /// 恢复任务
        /// </summary>
        /// <param name="taskId">任务ID</param>
        /// <returns>是否成功</returns>
        public async Task<bool> ResumeTaskAsync(string taskId)
        {
            // 检查正在运行的任务
            if (_runningTasks.TryGetValue(taskId, out BaseTask runningTask))
            {
                await runningTask.ResumeAsync();
                _logger.Info($"任务已恢复: {taskId}");
                OnTaskStatusChanged(new TaskStatusChangedEventArgs(runningTask, TaskState.Running));
                return true;
            }
            
            // 检查队列中的任务
            var queuedTask = _taskQueue.FirstOrDefault(t => t.TaskId == taskId);
            if (queuedTask != null)
            {
                await queuedTask.ResumeAsync();
                _logger.Info($"队列中的任务已恢复: {taskId}");
                OnTaskStatusChanged(new TaskStatusChangedEventArgs(queuedTask, TaskState.Pending));
                return true;
            }
            
            _logger.Warn($"找不到要恢复的任务: {taskId}");
            return false;
        }
        
        /// <summary>
        /// 取消任务
        /// </summary>
        /// <param name="taskId">任务ID</param>
        /// <returns>是否成功</returns>
        public async Task<bool> CancelTaskAsync(string taskId)
        {
            // 检查正在运行的任务
            if (_runningTasks.TryGetValue(taskId, out BaseTask runningTask))
            {
                await runningTask.CancelAsync();
                _logger.Info($"任务已取消: {taskId}");
                
                // 将任务从运行中移到已完成
                if (_runningTasks.TryRemove(taskId, out _))
                {
                    // 取消订阅事件
                    runningTask.ProgressChanged -= Task_ProgressChanged;
                    
                    _completedTasks.TryAdd(taskId, runningTask);
                }
                
                OnTaskStatusChanged(new TaskStatusChangedEventArgs(runningTask, TaskState.Canceled));
                return true;
            }
            
            // 检查队列中的任务
            var tempQueue = new ConcurrentQueue<BaseTask>();
            bool found = false;
            
            // 将不需要取消的任务重新入队
            while (_taskQueue.TryDequeue(out BaseTask task))
            {
                if (task.TaskId == taskId)
                {
                    await task.CancelAsync();
                    
                    // 取消订阅事件
                    task.ProgressChanged -= Task_ProgressChanged;
                    
                    _completedTasks.TryAdd(taskId, task);
                    _logger.Info($"队列中的任务已取消: {taskId}");
                    OnTaskStatusChanged(new TaskStatusChangedEventArgs(task, TaskState.Canceled));
                    found = true;
                }
                else
                {
                    tempQueue.Enqueue(task);
                }
            }
            
            // 将临时队列中的任务重新入队
            while (tempQueue.TryDequeue(out BaseTask task))
            {
                _taskQueue.Enqueue(task);
            }
            
            if (!found)
            {
                _logger.Warn($"找不到要取消的任务: {taskId}");
            }
            
            return found;
        }
        
        /// <summary>
        /// 获取任务状态
        /// </summary>
        /// <param name="taskId">任务ID</param>
        /// <returns>任务状态</returns>
        public TaskState GetTaskStatus(string taskId)
        {
            // 检查正在运行的任务
            if (_runningTasks.TryGetValue(taskId, out BaseTask runningTask))
            {
                return runningTask.Status;
            }
            
            // 检查队列中的任务
            var queuedTask = _taskQueue.FirstOrDefault(t => t.TaskId == taskId);
            if (queuedTask != null)
            {
                return queuedTask.Status;
            }
            
            // 检查已完成的任务
            if (_completedTasks.TryGetValue(taskId, out BaseTask completedTask))
            {
                return completedTask.Status;
            }
            
            return TaskState.Unknown;
        }
        
        /// <summary>
        /// 获取所有任务
        /// </summary>
        /// <returns>所有任务的列表</returns>
        public List<BaseTask> GetAllTasks()
        {
            var allTasks = new List<BaseTask>();
            
            // 添加运行中的任务
            allTasks.AddRange(_runningTasks.Values);
            
            // 添加队列中的任务
            allTasks.AddRange(_taskQueue);
            
            // 添加已完成的任务（最多添加10个最近完成的任务）
            allTasks.AddRange(_completedTasks.Values.OrderByDescending(t => t.CompleteTime).Take(10));
            
            return allTasks;
        }
        
        /// <summary>
        /// 获取任务
        /// </summary>
        /// <param name="taskId">任务ID</param>
        /// <returns>任务</returns>
        public BaseTask GetTask(string taskId)
        {
            // 检查正在运行的任务
            if (_runningTasks.TryGetValue(taskId, out BaseTask runningTask))
            {
                return runningTask;
            }
            
            // 检查队列中的任务
            var queuedTask = _taskQueue.FirstOrDefault(t => t.TaskId == taskId);
            if (queuedTask != null)
            {
                return queuedTask;
            }
            
            // 检查已完成的任务
            if (_completedTasks.TryGetValue(taskId, out BaseTask completedTask))
            {
                return completedTask;
            }
            
            return null;
        }
        
        /// <summary>
        /// 处理任务队列
        /// </summary>
        private async Task ProcessTasksAsync(CancellationToken cancellationToken)
        {
            while (_isRunning && !cancellationToken.IsCancellationRequested)
            {
                try
                {
                    // 如果当前运行的任务数小于最大并行任务数，则尝试执行新任务
                    if (_runningTasks.Count < _maxParallelTasks && _taskQueue.TryDequeue(out BaseTask task))
                    {
                        // 将任务添加到运行中的任务字典
                        _runningTasks.TryAdd(task.TaskId, task);
                        
                        // 异步执行任务
                        _ = Task.Run(async () =>
                        {
                            try
                            {
                                // 创建任务上下文
                                var context = new TaskContext
                                {
                                    CancellationToken = cancellationToken
                                };
                                
                                // 执行任务
                                OnTaskStatusChanged(new TaskStatusChangedEventArgs(task, TaskState.Running));
                                var result = await _executeTaskDelegate(task, context);
                                
                                // 任务完成后，从运行中的任务字典中移除，并添加到已完成的任务字典中
                                if (_runningTasks.TryRemove(task.TaskId, out _))
                                {
                                    // 取消订阅事件
                                    task.ProgressChanged -= Task_ProgressChanged;
                                    
                                    _completedTasks.TryAdd(task.TaskId, task);
                                }
                                
                                OnTaskStatusChanged(new TaskStatusChangedEventArgs(task, task.Status));
                            }
                            catch (Exception ex)
                            {
                                _logger.Error($"执行任务时发生异常: {task.TaskId}, 类型: {task.TaskType}", ex);
                                
                                // 任务异常时，从运行中的任务字典中移除，并添加到已完成的任务字典中
                                if (_runningTasks.TryRemove(task.TaskId, out _))
                                {
                                    // 取消订阅事件
                                    task.ProgressChanged -= Task_ProgressChanged;
                                    
                                    task.Status = TaskState.Failed;
                                    _completedTasks.TryAdd(task.TaskId, task);
                                }
                                
                                OnTaskStatusChanged(new TaskStatusChangedEventArgs(task, TaskState.Failed));
                            }
                        });
                    }
                    else
                    {
                        // 如果没有任务可执行，则等待一段时间
                        await Task.Delay(100, cancellationToken);
                    }
                }
                catch (OperationCanceledException)
                {
                    // 操作被取消，退出循环
                    break;
                }
                catch (Exception ex)
                {
                    _logger.Error("处理任务队列时发生异常", ex);
                    await Task.Delay(1000, cancellationToken);
                }
            }
            
            _logger.Info("任务处理线程已退出");
        }
        
        /// <summary>
        /// 触发任务状态变更事件
        /// </summary>
        /// <param name="e">事件参数</param>
        protected virtual void OnTaskStatusChanged(TaskStatusChangedEventArgs e)
        {
            TaskStatusChanged?.Invoke(this, e);
        }

        // 处理任务进度变化事件
        private void Task_ProgressChanged(object sender, int progress)
        {
            if (sender is BaseTask task)
            {
                _logger.Debug($"收到任务进度更新: {task.TaskId}, 进度: {progress}%");
                OnTaskStatusChanged(new TaskStatusChangedEventArgs(task, task.Status));
            }
        }
    }
    
    /// <summary>
    /// 任务状态变更事件参数
    /// </summary>
    public class TaskStatusChangedEventArgs : EventArgs
    {
        /// <summary>
        /// 任务
        /// </summary>
        public BaseTask Task { get; }
        
        /// <summary>
        /// 任务状态
        /// </summary>
        public TaskState Status { get; }
        
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="task">任务</param>
        /// <param name="status">任务状态</param>
        public TaskStatusChangedEventArgs(BaseTask task, TaskState status)
        {
            Task = task;
            Status = status;
        }
    }
} 